// 日志中间件

/**
 * 请求日志中间件 - 记录请求和响应信息
 * @returns {Function} 中间件函数
 */
function 请求日志() {
  return function(请求, 响应, 下一个) {
    // 请求开始时间
    const 开始时间 = Date.now();
    
    // 记录请求信息
    console.log(`[${获取当前时间()}] ${获取客户端IP(请求)} - ${请求.method} ${请求.url}`);
    
    // 如果是POST/PUT请求，记录请求体（不记录敏感信息）
    if (['POST', 'PUT', 'PATCH'].includes(请求.method)) {
      const 安全请求体 = 过滤敏感信息(请求.body);
      console.log(`[${获取当前时间()}] 请求体:`, 安全请求体);
    }
    
    // 捕获原始的end方法
    const 原始结束方法 = 响应.end;
    
    // 重写end方法以记录响应信息
    响应.end = function(...参数) {
      // 计算响应时间
      const 响应时间 = Date.now() - 开始时间;
      
      // 根据状态码选择日志级别
      if (响应.statusCode >= 500) {
        console.error(`[${获取当前时间()}] ${请求.method} ${请求.url} - 状态码: ${响应.statusCode} - 响应时间: ${响应时间}ms`);
      } else if (响应.statusCode >= 400) {
        console.warn(`[${获取当前时间()}] ${请求.method} ${请求.url} - 状态码: ${响应.statusCode} - 响应时间: ${响应时间}ms`);
      } else {
        console.info(`[${获取当前时间()}] ${请求.method} ${请求.url} - 状态码: ${响应.statusCode} - 响应时间: ${响应时间}ms`);
      }
      
      // 调用原始的end方法
      return 原始结束方法.apply(this, 参数);
    };
    
    // 继续处理请求
    下一个();
  };
}

/**
 * 错误日志中间件 - 记录错误信息
 * @returns {Function} 中间件函数
 */
function 错误日志() {
  return function(错误, 请求, 响应, 下一个) {
    console.error(`[${获取当前时间()}] 错误:`, {
      方法: 请求.method,
      路径: 请求.url,
      错误信息: 错误.message,
      堆栈: 错误.stack
    });
    
    // 继续处理错误
    下一个(错误);
  };
}

/**
 * 获取当前时间字符串
 * @returns {string} 格式化的时间字符串
 */
function 获取当前时间() {
  return new Date().toISOString();
}

/**
 * 获取客户端真实IP地址
 * @param {Object} 请求 - Express请求对象
 * @returns {string} IP地址
 */
function 获取客户端IP(请求) {
  return (
    请求.headers['x-forwarded-for'] || 
    请求.headers['x-real-ip'] || 
    请求.connection.remoteAddress || 
    请求.socket.remoteAddress
  );
}

/**
 * 过滤请求体中的敏感信息
 * @param {Object} 请求体 - 请求体数据
 * @returns {Object} 过滤后的请求体
 */
function 过滤敏感信息(请求体) {
  if (!请求体 || typeof 请求体 !== 'object') {
    return 请求体;
  }
  
  // 创建请求体的副本
  const 安全副本 = { ...请求体 };
  
  // 定义需要过滤的敏感字段
  const 敏感字段 = ['password', '密码', 'token', 'secret', '密钥'];
  
  // 过滤敏感字段
  敏感字段.forEach(字段 => {
    if (安全副本[字段]) {
      安全副本[字段] = '*** 已过滤 ***';
    }
  });
  
  return 安全副本;
}

/**
 * 性能监控中间件 - 监控响应时间
 * @returns {Function} 中间件函数
 */
function 性能监控() {
  return function(请求, 响应, 下一个) {
    const 开始时间 = process.hrtime();
    
    响应.on('finish', () => {
      const 结束时间 = process.hrtime(开始时间);
      const 执行时间 = 结束时间[0] * 1000 + 结束时间[1] / 1000000; // 转换为毫秒
      
      // 记录长时间运行的请求
      if (执行时间 > 1000) { // 超过1秒的请求
        console.warn(`[性能警告] ${请求.method} ${请求.url} - 执行时间: ${执行时间.toFixed(2)}ms`);
      }
    });
    
    下一个();
  };
}

module.exports = {
  请求日志,
  错误日志,
  性能监控
};